#include "ipSobel.h"
#include "ipCanny.h"
#include "ipRoberts.h"
#include "ipPrewitt.h"
#include "xtprobeImageDiskXFile.h"
#include "ipCore.h"
#include "tp4.h"
//#include "util.h"

ContourImg::ContourImg(char *name)
{
	image_in = new ImageGray();
  	image_in->setBOption("verbose",false);
  
  	ImageDiskXFile *image_file = new xtprobeImageDiskXFile(name,"r");
	file_name = (char*) malloc (sizeof(char)*longueur(name)+1);
	
	strcpy(file_name,name);
	image_in->loadImageXFile(image_file);

  	//on libere l'espace occupe par image_file
  	delete image_file; 
	//print("Merci\n");
}


void ContourImg::changeEdges(ImageGray*img)
{

	for(int k = 0;k<img->height;k++){
		for(int j = 0;j<img->width;j++)
		if((int)img->get(k,j)[0] == 0)	
			img->get(k,j)[0] = 255;    
		else
			img->get(k,j)[0] =0;  				
 	 } 

	//DiskXFile *img_file = new DiskXFile("test3.pgm","w");
	//img->saveXFile(img_file);
}
//Parametres color la couleur de l'image que l'on cherche dans l'image
//color = 0 ou 255
//img image dans laquelle on cherche la couleur color


int ContourImg::nuberPixelsOfColor(ImageGray*img, int color)
{
	int nb = 0;
	for(int k = 0;k<img->height;k++){
		for(int j = 0;j<img->width;j++)
		if((int)img->get(k,j)[0] == color)	
			//nb += color;    
		 	nb += 1;  			
 	 }
	
	return nb; 
}


void ContourImg::initCompare(char*file)
{
	image_compare = new ImageGray();
  	image_compare->setBOption("verbose",false);
  
  	ImageDiskXFile *image_file = new xtprobeImageDiskXFile(file,"r");
	
	//strcpy(file_name,name);
	image_compare->loadImageXFile(image_file);
  	//on libere l'espace occupe par image_file
  	delete image_file; 
}


int ContourImg::nombreCommun(ImageGray *image_ref,ImageGray *image_in)
{       
	int nb_commun = 0;
	int N=image_in->height;
	int M=image_in->width-1;
	//traitement des mixels au centre
	for(int i=1;i< image_in->height-1;i++)
	for(int j=1; j<image_in->width-1;j++)
    		if(image_in->get(i,j)[0]==255 && (0 == image_ref->get(i,j)[0]||0 == image_ref->get(i-1,j-1)[0]||0 == image_ref->get(i-1,j)[0]||0 == image_ref->get(i-1,j+1)[0]||0 == image_ref->get(i,j-1)[0]||0 == image_ref->get(i,j+1)[0]||0 == image_ref->get(i+1,j-1)[0]||0 == image_ref->get(i+1,j)[0]||0 == image_ref->get(i+1,j+1)[0]))
			nb_commun++;

//traitement des pixels de la premiere ligne
	for(int j=1; j<image_in->width-1;j++)
		if(image_in->get(0,j)[0] ==255 &&(0 == image_ref->get(0,j)[0]||0 == image_ref->get(0,j-1)[0]||0 == image_ref->get(0,j+1)[0]||0 == image_ref->get(1,j)[0]||0 == image_ref->get(1,j-1)[0]||0 == image_ref->get(1,j+1)[0])) nb_commun++;


//traitement des pixels de la deriere ligne
	for(int j=1; j<image_in->width-1;j++)
		if(image_in->get(N-1,j)[0]==255 &&(0 == image_ref->get(N-1,j)[0]||0 == image_ref->get(N-1,j-1)[0]||0 == image_ref->get(N-1,j+1)[0]||0 == image_ref->get(N-2,j)[0]||0 == image_ref->get(N-2,j-1)[0]||0 == image_ref->get(N-2,j+1)[0])) nb_commun++;


//traitement des pixels de la premiere colonne
	for(int i=1; i<image_in->height-1;i++)
		if(image_in->get(i,0)[0]==255 &&(0 == image_ref->get(i,0)[0]||0 == image_ref->get(i-1,0)[0]||0 == image_ref->get(i+1,0)[0]||0 == image_ref->get(i-1,1)[0]||0 == image_ref->get(i,1)[0]||0 == image_ref->get(i+1,1)[0])) nb_commun++;

//traitement des pixels de la deriere colonne

	for(int i=1; i<image_in->height-1;i++)
		if(image_in->get(i,M)[0]==255 &&(0 == image_ref->get(i-1,M)[0]||0 == image_ref->get(i+1,M)[0]||0 == image_ref->get(i-1,M-1)[0]||0 == image_ref->get(i,M-1)[0]||0 == image_ref->get(i,M)[0]||0 == image_ref->get(i+1,M-1)[0])) nb_commun++;

//traitement angle superieure gauche
if(image_in->get(0,0)[0]==255 && (0==image_ref->get(0,0)[0]||0 == image_ref->get(0,1)[0]||0==image_ref->get(1,0)[0]||0==image_ref->get(1,1)[0])) nb_commun++;
//traitement angle superieure droit

if(image_in->get(0,M)[0]==255 && (0==image_ref->get(0,M)[0]||0 == image_ref->get(0,M-1)[0]||0==image_ref->get(1,M)[0]||0==image_ref->get(1,M-1)[0])) nb_commun++;


//traitement angle inferieure droit

if(image_in->get(N-1,M)[0]==255 && (0 == image_ref->get(N-1,M)[0]||0==image_ref->get(N-1,M-1)[0]||0==image_ref->get(N-2,M)[0]||0==image_ref->get(N-2,M-1)[0])) nb_commun++;

//traitement angle inferieure gauche

if(image_in->get(N-1,0)[0] == 255 && (0 == image_ref->get(N-1,0)[0]||0 == image_ref->get(N-1,1)[0]||0==image_ref->get(N-2,0)[0]||0==image_ref->get(N-2,1)[0])) nb_commun++;

	return nb_commun; 

}


void ContourImg::sobel(real threshold)
{
	ipCore *sobel = NULL;
 
 	sobel = new ipSobel(image_in->width, image_in->height, "gray");
 	sobel->setBOption("verbose", false);
 	sobel->setROption("threshold", threshold);
 	sobel->init();
 	sobel->process(image_in);
 	
 	ImageGray *image_out = new ImageGray();
 	image_out->setBOption("verbose", false);
 
	image_out->copyFrom(image_in->width, image_in->height, sobel->seq_out->frames[0], "gray");
 	image_out->save(newName(file_name,(char*)"_gradientX.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, sobel->seq_out->frames[1], "gray");
 	image_out->save(newName(file_name,(char*)"_gradientY.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, sobel->seq_out->frames[2], "gray");
 	image_out->save(newName(file_name,(char*)"_gradient.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, sobel->seq_out->frames[3], "gray");
 	image_out->save(newName(file_name,(char*)"_Sobel.pgm"));
	changeEdges(image_out);
 
 	delete sobel;
	delete image_out;
}


void ContourImg::prewitt(float threshold)
{

	ipCore *priwit = NULL;
 
 	priwit = new ipPrewitt(image_in->width, image_in->height, "gray");
 	priwit->setBOption("verbose",false);
 	priwit->setROption("threshold", threshold);
 	priwit->init();
 	priwit->process(image_in);
 	
 	ImageGray *image_out = new ImageGray();
 	image_out->setBOption("verbose", false);
 
	image_out->copyFrom(image_in->width, image_in->height, priwit->seq_out->frames[0], "gray");
 	image_out->save(newName(file_name,(char*)"_gradientx.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, priwit->seq_out->frames[1], "gray");
 	image_out->save(newName(file_name,(char*)"_gradienty.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, priwit->seq_out->frames[2], "gray");
 	image_out->save(newName(file_name,(char*)"_gradient.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, priwit->seq_out->frames[3], "gray");
 	image_out->save(newName(file_name,(char*)"_prewitt.pgm"));
 
 	delete priwit;	
	delete image_out;
}

void ContourImg::roberts(float threshold)
{

	ipCore *robert = NULL;
 
 	robert = new ipRoberts(image_in->width, image_in->height, "gray");
 	robert->setBOption("verbose", false);
 	robert->setROption("threshold", threshold);
 	robert->init();
 	robert->process(image_in);
 	
 	ImageGray *image_out = new ImageGray();
 	image_out->setBOption("verbose", false);
 
	image_out->copyFrom(image_in->width, image_in->height, robert->seq_out->frames[0], "gray");
 	image_out->save(newName(file_name,(char*)"_gradientx.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, robert->seq_out->frames[1], "gray");
 	image_out->save(newName(file_name,(char*)"_gradienty.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, robert->seq_out->frames[2], "gray");
 	image_out->save(newName(file_name,(char*)"_gradient.pgm"));

 	image_out->copyFrom(image_in->width, image_in->height, robert->seq_out->frames[3], "gray");
 	image_out->save(newName(file_name,(char*)"_roberts.pgm"));
 
 	delete robert;
	delete image_out;
}

void ContourImg::canny(real threshold)
{
	ipCore *canny = NULL;
 
	canny = new ipCanny(image_in->width, image_in->height, "gray", threshold);
 	canny->setBOption("verbose", false);
	canny->process(image_in);
	
 	ImageGray *image_out = new ImageGray();
	image_out->setBOption("verbose", false);
 
 	image_out->copyFrom(image_in->width, image_in->height, canny->seq_out->frames[0], "gray");
 	image_out->save(newName(file_name,(char*)"_gradientxy.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, canny->seq_out->frames[1], "gray");
 	image_out->save(newName(file_name,(char*)"_gradient.pgm"));
 
 	image_out->copyFrom(image_in->width, image_in->height, canny->seq_out->frames[2], "gray");
 	image_out->save(newName(file_name,(char*)"_canny.pgm"));
 
 	delete canny;
	delete image_out;
}

char* ContourImg::newName(char*oldname,char*additionName)
{
	//on soustrait 4 pour fairepartir les informations du type de l'image
	int l = longueur(oldname) - 4;
	int size = l + longueur(additionName) + 1; 

	char* nouveau = (char*)malloc(sizeof(char)*(l+longueur(additionName) + 1));
	int i = 0;
	for(i = 0;i<l;i++)
		nouveau[i] = oldname[i]; 
	//printf("\t%s\n",nouveau);
	for(int t=0,k=i; k< size;t++,k++)
		nouveau[k]=additionName[t];

	return (nouveau);
	
}


int ContourImg::longueur(char* chaine)
{

	int k =0;
	for(k=0;chaine[k]!='\0';k++);
	
	return(k);
		
}
